package com.caigou.service.impl;

import com.caigou.bean.cms.entity.Picture;
import com.caigou.bean.cms.entity.PictureFolder;
import com.caigou.bean.cms.param.PictureFolderParam;
import com.caigou.bean.cms.param.PictureQueryParam;
import com.caigou.bean.cms.param.PictureRecycleQueryParam;
import com.caigou.bean.cms.param.PictureUseParam;
import com.caigou.bean.exam.entity.Users;
import com.caigou.component.OSSComponent;
import com.caigou.component.SnowflakeComponent;
import com.caigou.constant.NewsConstant;
import com.caigou.enums.FailResultEnum;
import com.caigou.enums.PictureEnum;
import com.caigou.enums.SuccessResultEnum;
import com.caigou.mapper.cms.PictureFolderMapper;
import com.caigou.mapper.cms.PictureMapper;
import com.caigou.service.PictureService;
import com.caigou.util.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

@Slf4j
@Service("pictureService")
public class PictureServcieImpl implements PictureService {

    @Resource
    private PictureMapper pictureMapper;
    @Resource
    private PictureFolderMapper pictureFolderMapper;

    @Resource
    private OSSComponent ossComponent;

    @Resource
    private SnowflakeComponent snowflakeComponent;// 雪花UUID组件

    @Value("${watermarkSourceFile}")
    private String watermarkSourceFile;

//    @Autowired
//    @Lazy
//    private PictureService pictureService;

//    @Autowired
//    ApplicationContext applicationContext;

    private static final int ZOOM_WIDTH = 200;
    private static final int ZOOM_HEIGHT = 200;
    private static final double ZOOM_QUALITY = 0.8;
    private static final float WATERMARK_TRANSPARENCY = 0.5f;
    private static final float WATERMARK_SCALE = 1.0f;
    private static final float WATERMARK_QUALITY = 1.0f;


    /**
     * 根据图片文件夹id、关键词，分页查询图片,不包括子文件夹
     * @param folderId 文件夹
     * @param keyword 关键词
     * @param pageNum 页码
     * @param pageSize 每页数据数量
     * @return PageInfo
     */
    public PageInfo<Picture> queryPictureByFolderId(Integer folderId, String keyword, Integer pageNum, Integer pageSize){
        Page<?> page = PageHelper.startPage(pageNum, pageSize);
        List<Picture> pictureList = pictureMapper.queryPicture(folderId, keyword);
        PageInfo<Picture> picturePageInfo = new PageInfo<>(pictureList);
        return picturePageInfo;
    }

    /**
     * 查询某图片库目录及其子目录下的所有图片，根据关键词，分页查询
     * @param folderId
     * @param keyword
     * @param pageNum
     * @param pageSize
     * @return
     */
    public PageInfo<Picture> queryPictureIncludingSubfolders(Integer folderId, String keyword, Integer pageNum, Integer pageSize){
        PictureFolder picturefolder = pictureFolderMapper.selectByPrimaryKey(folderId);
        String path = picturefolder.getPath();
        Page<?> page = null;
        if(pageNum!=null && pageSize !=null){
            page = PageHelper.startPage(pageNum, pageSize);
        }
        log.info("page={}", page);
        List<Picture> pictureList = pictureMapper.queryPictureByPath(path, keyword);
        PageInfo<Picture> picturePageInfo = new PageInfo<>(pictureList);
        return picturePageInfo;
    }

    /**
     * 查询某图片库目录及其子目录下的所有图片:支持高级搜索
     * @param pictureQueryParam
     * @param user
     * @return
     */
    public PageInfo<Picture> queryPictureIncludingSubfolders(PictureQueryParam pictureQueryParam, Users user){
        Integer folderId = pictureQueryParam.getFolderId();
        if(folderId!=null){
            PictureFolder picturefolder = pictureFolderMapper.selectByPrimaryKey(folderId);
            String path = picturefolder.getPath();
            pictureQueryParam.setPath(path);
        }
        Integer imageType = pictureQueryParam.getImageType();
        if(imageType!=null){
            String strImageType = null;
            if(imageType==PictureEnum.PICTURE_JPG.getType()){
                strImageType = PictureEnum.PICTURE_JPG.getNote();
            }else if(imageType==PictureEnum.PICTURE_PNG.getType()){
                strImageType=PictureEnum.PICTURE_PNG.getNote();
            }else if(imageType==PictureEnum.PICTURE_GIF.getType()){
                strImageType=PictureEnum.PICTURE_GIF.getNote();
            }
            pictureQueryParam.setStrImageType(strImageType);
        }
        if(pictureQueryParam.getOnlyMine()!=null && pictureQueryParam.getOnlyMine()==1){//只看自己
            pictureQueryParam.setUploadUserId(user.getUserid());
        }
        if(pictureQueryParam.getDeleteStatus()==null){
            pictureQueryParam.setDeleteStatus(0);
        }
        Long intKeyword = null;
        try{
            intKeyword = Long.parseLong(pictureQueryParam.getKeyword());
            pictureQueryParam.setIntKeyword(intKeyword);
        }catch(Exception e){
            //log.error(e.getMessage(), e);
        }

        Page<?> page = PageHelper.startPage(pictureQueryParam.getPageNum(), pictureQueryParam.getPageSize());
        List<Picture> pictureList = pictureMapper.advancedQueryPictureByPath(pictureQueryParam);

        //设置文件夹全路径名称
        buildFullFolderName(pictureList);

        PageInfo<Picture> picturePageInfo = new PageInfo<>(pictureList);
        return picturePageInfo;
    }

    public PictureFolder getPictureFolderById(Integer folderId){
        return pictureFolderMapper.selectByPrimaryKey(folderId);
    }

    private void  buildFullFolderName(List<Picture> pictureList){
        for(Picture picture:pictureList){
            Integer pictureFolderId = picture.getFolderId();
            PictureFolder item = getPictureFolder(pictureFolderId);
            String itemPath = item.getPath();
            String[] array = itemPath.split("/");
            StringBuffer stringBuffer = new StringBuffer();
            for(int i=1; i<array.length; i++){
                Integer subPictureFolderId = Integer.parseInt(array[i]);
                PictureFolder subItem = getPictureFolder(subPictureFolderId);
                if(i<array.length-1){
                    stringBuffer.append(subItem.getFolderName()).append("/");
                }else{
                    stringBuffer.append(subItem.getFolderName());
                }
            }
            picture.setFullFolderName(stringBuffer.toString());
        }

    }

    /**
     * 通过图片库某目录id获取该目录下所有的图片目录列表及个人图片库
     * @param superId
     * @return
     */
    public List<PictureFolder> listPictureFolderBySuperId(Integer superId, String userId){
        List<PictureFolder> list = pictureFolderMapper.listPictureFolderBySuperId(superId, userId);
        return list;
    }

    public int savePictureFolder(PictureFolder pictureFolder){
        return pictureFolderMapper.insertSelective(pictureFolder);
    }

    /**
     * 创建个人图片库根文件夹（个人库）
     * @param userId
     * @return
     */
//    @Transactional
//    public int createPersonalRootPictureFolder(String userId, PictureFolder rootPictureFolder){
//        PictureFolder pictureFolder = new PictureFolder();
//        long timestamp = System.currentTimeMillis();
//        Date current = new Date(timestamp);
//        pictureFolder.setCreateTime(current);
//        pictureFolder.setUpdateTime(current);
//        pictureFolder.setFolderName("个人库");
//        pictureFolder.setFolderUserId(userId);
//        pictureFolder.setFolderType(2);
//        pictureFolder.setSuperId(1);
//        pictureFolder.setLevel(2);
//        int count = this.savePictureFolder(pictureFolder);
//        if(count>0){
//            String path = rootPictureFolder.getPath()+pictureFolder.getId()+"/";
//            pictureFolder.setPath(path);
//            pictureFolder.setUpdateTime(new Date(System.currentTimeMillis()));
//            int ucount = pictureFolderMapper.updatePath(pictureFolder);
//            log.info("更新用户={}个人库根文件夹的path信息为{}结果={}", userId, path, ucount);
//        }
//        return count;
//    }

    /**
     * 获取图片库根文件夹（系统只有一个根文件夹）
     * @return
     */
    public PictureFolder getRootPictureFolder(){
        PictureFolder rootPictureFolder = pictureFolderMapper.getRootPictureFolder();
//        //查询该用户的个人库文件夹是否已经创建
//        int personalRootCount = pictureFolderMapper.getPersonalRootPictureFolderCount(userId);
//        if(personalRootCount==0){
//            int count = this.createPersonalRootPictureFolder(userId, rootPictureFolder);
//            log.info("为用户={}创建图片个人库根文件夹个人库结果={}", userId, count);
//        }
        return rootPictureFolder;
    }

    /**
     * 创建图片库文件夹
     * @param param
     * @return
     */
    @Transactional
    public Result createPictureFolder(PictureFolderParam param, String userId){
        //获取父文件夹
        PictureFolder parent = this.getPictureFolderById(param.getSuperId());
        if(parent == null){
            return Result.error("图片库父文件夹不存在");
        }
        //获取父文件夹信息
        Integer parentLevel = parent.getLevel();
        String parentPath = parent.getPath();
        if(parentLevel<1){
            log.warn("图片父目录级别level错误，leve值应该大于0，实际level={}", parentLevel);
            return Result.error("图片库父文件夹级别错误");
        }

//        if(parent.getFolderType().intValue()!=param.getFolderType().intValue()){
//            log.warn("创建图片文件夹与父级文件夹类型不一致");
//            return Result.error("创建图片文件夹类型错误");
//        }
        //保存本级文件夹信息
        PictureFolder pictureFolder = new PictureFolder();
        long timestamp = System.currentTimeMillis();
        Date current = new Date(timestamp);
        pictureFolder.setCreateTime(current);
        pictureFolder.setUpdateTime(current);
        pictureFolder.setFolderName(param.getFolderName());
        pictureFolder.setFolderUserId(userId);
        pictureFolder.setSuperId(param.getSuperId());
        pictureFolder.setLevel(parentLevel+1);
        pictureFolder.setDeleteStatus(NewsConstant.FOLDER_NORMAL);
        pictureFolder.setIsDefaultFolder(NewsConstant.DEFAULT_FOLDER_NO);
        int scount = 0;
        try{
            scount = savePictureFolder(pictureFolder);
        }catch(DataAccessException e){
            log.error(e.getMessage(), e);
            return Result.custom(400, "创建文件夹名称重复", "创建文件夹名称重复");
        }

        //更新本级文件夹path
        Integer folderId = pictureFolder.getId();
        String path = parentPath+folderId+"/";
        pictureFolder.setPath(path);
        pictureFolder.setUpdateTime(new Date(System.currentTimeMillis()));
        int ucount = pictureFolderMapper.updatePath(pictureFolder);
        log.info("保存图片目录结果={}， 更新图片目录结果={}, id={}，userId={}", scount, ucount, folderId, userId);

        //更新父级文件夹hashSubfolder
        if(parent.getHasSubfolder().intValue()==0){//父级文件夹没有子文件夹
            parent.setHasSubfolder(1);
            parent.setUpdateTime(new Date(System.currentTimeMillis()));
            int count = pictureFolderMapper.updateHasSubfolder(parent);
            log.info("更新父级图片目录hasSubfolder结果={}，id={}", count, parent.getId());
        }

        return Result.success("用户创建图片库文件夹成功");
    }

    /**
     * 根据图片目录id获取图片目录
     * @param id
     * @return
     */
    public PictureFolder getPictureFolder(Integer id){
        return pictureFolderMapper.selectByPrimaryKey(id);
    }

    /**
     * 删除图片库文件夹，实际是逻辑删除
     * @param id 图片库文件夹id
     * @return
     */
    public Result deletePictureFolder(Integer id){
        PictureFolder pictureFolder = pictureFolderMapper.selectByPrimaryKey(id);
        if(pictureFolder.getIsDefaultFolder()==1){
            return Result.error(FailResultEnum.PICTURE_FOLDER_ERROR, "图片文件夹为默认文件夹，不能删除");
        }
        //判断是否有子文件夹
        if(pictureFolder.getHasSubfolder()==1){
            return Result.error(FailResultEnum.PICTURE_FOLDER_ERROR, "图片文件夹有子文件夹，不能删除");
        }
//        int subfolderCount = pictureFolderMapper.getSubfolderCount(id);
//        if(subfolderCount>0){
//            return Result.error(FailResultEnum.PICTURE_FOLDER_ERROR, "图片文件夹有子文件夹，不能删除");
//        }
        //判断是否有图片文件
        int pictureCount = pictureMapper.getPictureCount(id);
        if(pictureCount>0){
            return Result.error(FailResultEnum.PICTURE_FOLDER_ERROR, "图片库文件夹中有图片，不能删除");
        }
//        //逻辑删除，更新delete_status状态
//        pictureFolder.setDeleteStatus(NewsConstant.FOLDER_DELETE);
//        pictureFolder.setUpdateTime(new Date(System.currentTimeMillis()));
//        int deleteCount = pictureFolderMapper.updateDeleteStatus(pictureFolder);
        //物理删除
        int deleteCount = pictureFolderMapper.deleteByPrimaryKey(id);
        if(deleteCount>0){
            //判断父文件夹下面还有没有状态正常的子文件夹
            Integer superId = pictureFolder.getSuperId();
            int siblingCount = pictureFolderMapper.getSubfolderCount(superId);
            if(siblingCount==0){
                PictureFolder parent = new PictureFolder();
                parent.setId(superId);
                parent.setHasSubfolder(0);
                parent.setUpdateTime(new Date(System.currentTimeMillis()));
                int pCount = pictureFolderMapper.updateHasSubfolder(parent);
                log.info("更新图片库父文件夹id={}的hasSubfolder状态为0,更新结果为{}", superId, pCount);
            }
            return Result.success(SuccessResultEnum.SUCCESS, "删除图片库文件夹成功");
        }else{
            return Result.error(FailResultEnum.PICTURE_FOLDER_ERROR, "删除图片库文件夹失败");
        }
    }

    /**
     * 获取图片库默认文件夹
     * @return
     */
    public PictureFolder getDefaultPictureFolder(){
        return pictureFolderMapper.getDefaultPictureFolder();
    }


    /**
     * 保存图片
     * @param picture
     * @return
     */
    public int savePicture(Picture picture){
        return pictureMapper.insertSelective(picture);//pictureMapper.insert(picture);
    }

    /**
     * 上传图片文件，支持多图上传
     * @param files
     * @param folderId
     * @param userId
     * @return
     */
    public Result uploadPicture(MultipartFile[] files, String[] pictureAlts, String[] pictureInfos,
                                Integer folderId, String pictureSource, String photographer, String userId){
        PictureFolder pictureFolder = null;
        if(folderId==null){
            pictureFolder = pictureFolderMapper.getDefaultPictureFolder();
        }else{
            pictureFolder = getPictureFolder(folderId);
        }
        if(pictureFolder==null){
            return Result.error("图片文件夹id错误，没有这个图片文件夹或者没有默认图片文件夹");
        }
        String path = pictureFolder.getPath();
        int index = path.indexOf("/");
        String picFolder = NewsConstant.PICTURE_ROOT+path.substring(index);
        log.info("上传文件到oss的目录={}", picFolder);
        //多文件上传
        int failCount = 0;//文件上传失败数量
        int successCount = 0;//文件上传成功数量
        int fileCount = files.length;
        if(fileCount==1 && pictureAlts.length==0){
            pictureAlts = new String[1];
            pictureAlts[0] = "";
        }
        if(fileCount==1 && pictureInfos.length==0){
            pictureInfos = new String[1];
            pictureInfos[0] = "";
        }
        PictureService proxy = (PictureService) AopContext.currentProxy();
        StringBuffer sb = new StringBuffer("第");
        for(int i=0; i<files.length; i++){
            MultipartFile multipartFile = files[i];
            log.info("before 上传图片pictureInfo={}, i={}", pictureInfos[i], i);
            String pictureAlt = pictureAlts[i];
            String pictureInfo = pictureInfos[i];
            log.info("pictureAlt's length={}, pictureInfo' length={}", pictureAlts.length, pictureInfos.length);
            int uploadResult = 0;
            try{
//                //方法1：通过applicationContext获取pictureService===使用 ApplicationContext 上下文对象获取该对象
//                PictureService bean = (PictureService)applicationContext.getBean("pictureService");
//                uploadResult = bean.uploadPicture(file, pictureAlt, pictureInfo, i, folderId, pictureSource, photographer, picFolder, userId);
//                //方法2：使用 AopContext.currentProxy() 获取代理对象,但是需要配置exposeProxy=true

                uploadResult = proxy.uploadPicture(multipartFile, pictureAlt, pictureInfo, i, folderId, pictureSource, photographer, picFolder, userId);;
                  //方法3：通过调用另外一个service中的Transactional方法
                //uploadResult = uploadPicture(file, i, folderId, picFolder);
                //uploadResult = singlePictureService.uploadPicture(file, i, folderId, picFolder);
                //方法4：通过类内部通过@Autowired将本身bean引入，然后通过调用自身bean，从而实现使用AOP代理操作。
                //uploadResult = this.pictureService.uploadPicture(file, pictureAlt, pictureInfo, i, folderId, pictureSource, photographer, picFolder, userId);;
                //uploadResult = uploadPicture(file, pictureAlt, pictureInfo, i, folderId, pictureSource, photographer, picFolder, userId);;
            }catch(Exception e){
                log.error(e.getMessage(), e);
            }
            if(uploadResult>0){
                successCount++;
            }else{
                failCount++;
                sb.append((i+1)).append("、");
            }
        }

        if(failCount==0){//全部成功
            return Result.success("图片上传成功");
        }else if(successCount==0){//全部失败
            return Result.error(failCount+"个图片上传全部失败", failCount+"个图片上传全部失败");
        }else{//部分成功、部分失败
            sb.deleteCharAt(sb.length() - 1);//删除最后一个字符
            return Result.custom(400,failCount+"个（"+sb.toString()+")图片上传失败,"+successCount+"个图片上传成功",failCount+"个（"+sb.toString()+")图片上传失败,"+successCount+"个图片上传成功");
        }

    }

    /**
     *
     * @param multipartFile
     * @param folderId
     * @param picFolder
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public int uploadPicture(MultipartFile multipartFile, String pictureAlt, String pictureInfo, int i, Integer folderId,
                             String pictureSource, String photographer, String picFolder, String userId) {
        File zoomFile = null;
        File watermarkFile = null;
        File file = null;
        try{
            String fileName = multipartFile.getOriginalFilename();
            log.info("第{}个文件，fileName={}", i, fileName);
            String fileExtension = "";
            int idx = fileName.lastIndexOf(".");
            if(idx>0){
                fileExtension = fileName.substring(idx);
                //String imageFileFormat = fileExtension.substring(1);
            }else{
                log.error("上传文件错误，没有扩展名, fileName={}", fileName);
                return 0;
            }
            //文件重命名
            long snowflakeId = snowflakeComponent.getInstance().nextId();
            String newFileName = snowflakeId+fileExtension;
            String newZoomFileName = "small_"+snowflakeId+fileExtension;
            String newWaterMarkFileName = "watermark_"+snowflakeId+fileExtension;

            InputStream originInputStream = multipartFile.getInputStream();
            //利用Thumbnails压缩图片
            String zoomFileName = "small_"+fileName;
            //zoomFile为临时压缩图片文件，务必上传完后删除
            zoomFile = new File(newZoomFileName);

            //waterMarkFile为临时水印图片文件，务必上传后删除
            String watermarkFileName = "watermark_"+fileName;
            watermarkFile = new File(newWaterMarkFileName);
            //BufferedImage bufferedImage = handleTextWaterMark("www.caigou2003.com");
            //Thumbnails.of(file.getInputStream()).scale(1.0).outputQuality(1.0).watermark(bufferedImage).toFile(watermarkFile);
            //水印图片
            File waterFile = new File(watermarkSourceFile);//org.springframework.util.ResourceUtils.getFile("classpath:watermark.png");
            if(fileExtension.equalsIgnoreCase(".gif")){//gif动态图片
                file = FileUtil.multipartFileToFile(multipartFile);
                //缩略图
                ImageRemarkUtil.makeGif(file, zoomFile, ZOOM_WIDTH, ZOOM_HEIGHT);
                //水印图
                ImageRemarkUtil.addImageWatermarkToGif(file, waterFile, watermarkFile);
            }else{//jpg\pgn图片
                //缩略图
                Thumbnails.of(multipartFile.getInputStream()).size(ZOOM_WIDTH, ZOOM_HEIGHT).keepAspectRatio(true).outputQuality(ZOOM_QUALITY).toFile(zoomFile);
                //水印图
                Thumbnails.of(multipartFile.getInputStream()).scale(WATERMARK_SCALE).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(waterFile), WATERMARK_TRANSPARENCY).outputQuality(WATERMARK_QUALITY).toFile(watermarkFile);
            }

            InputStream zoomInputStream = new FileInputStream(zoomFile);
            InputStream watermarkInputStream = new FileInputStream(watermarkFile);

            //同时上传原图、压缩图、水印图到oss
            //String fileUrl = ossComponent.uploadOriginAndZoomToOSS(originInputStream, zoomInputStram, fileName, picFolder);

            //上传原图
            String fileUrl = ossComponent.uploadToOSS(originInputStream, fileName, newFileName, picFolder);
            //上传水印图
            String watermarkUrl = ossComponent.uploadToOSS(watermarkInputStream, watermarkFileName, newWaterMarkFileName, picFolder);
            //上传缩略图
            String zoomFileUrl = ossComponent.uploadToOSS(zoomInputStream, zoomFileName, newZoomFileName, picFolder);

            if(fileUrl!=null&&fileUrl.length()>0){
                if(folderId==null){//folderId值为null，则上传到默认文件夹
                    PictureFolder defaultFolder = pictureFolderMapper.getDefaultPictureFolder();
                    if(defaultFolder==null){
                        log.error("图片库没有默认文件夹，上传文件失败");
                        return 0;
                    }else{
                        folderId = defaultFolder.getId();
                    }
                }
                long timestamp = System.currentTimeMillis();
                Date currentDate = new Date(timestamp);
                Picture picture = new Picture();
                picture.setFolderId(folderId);
                picture.setUpdateTime(currentDate);
                picture.setPictureName(multipartFile.getOriginalFilename());
                picture.setPictureUrl(fileUrl);
                picture.setCreateTime(currentDate);
                picture.setPictureAlt(pictureAlt);
                picture.setPictureSize(new Long(multipartFile.getSize()).intValue()/(1024));
//                picture.setPictureIsUse(0);
                picture.setPictureFormat(multipartFile.getContentType());

                picture.setPictureInfo(pictureInfo);
                picture.setPictureSource(pictureSource);
                picture.setPhotographer(photographer);
                picture.setUploadUserId(userId);
                picture.setDeleteStatus(0);

                picture.setPictureZoomUrl(zoomFileUrl);
                picture.setPictureWatermarkUrl(watermarkUrl);

//                //获取图片的高度、宽度
//                BufferedImage image = null;
//                try {
//                    image = ImageIO.read(file.getInputStream());
//                    if (image != null) {
//                        picture.setPictureWidth(image.getWidth());//获取图片宽度，单位px
//                        picture.setPictureHeight(image.getHeight());//获取图片高度，单位px
//
//                    }else{//如果image=null 表示上传的不是图片格式
//                        picture.setPictureWidth(0);
//                        picture.setPictureHeight(0);
//                    }
//
//                } catch (IOException e) {
//                    log.error(e.getMessage(), e);
//                    picture.setPictureWidth(0);
//                    picture.setPictureHeight(0);
//                } finally {
//                    //释放图片内存
//                    if(image!=null) {
//                        image.getGraphics().dispose();
//                    }
//                }
                //获取图片宽度、高度及拍摄时间
                File tempFile = null;
                try{
                    tempFile = FileUtil.multipartFileToFile(multipartFile);
                    String[] photos = ExifUitl.readExif(tempFile);
                    int width = 0;
                    int height = 0;
                    try{
                        String strWidth = photos[0];
                        int index = strWidth.indexOf("pixels");
                        if(index>0){
                            strWidth = strWidth.substring(0, index-1);
                        }
                        width = Integer.parseInt(strWidth);
                    }catch (Exception e){
                        log.error(e.getMessage(), e);
                    }
                    try{
                        String strHeight = photos[1];
                        int index = strHeight.indexOf("pixels");
                        if(index>0){
                            strHeight = strHeight.substring(0, index-1);
                        }
                        height = Integer.parseInt(strHeight);
                    }catch(Exception e){
                        log.error(e.getMessage(), e);
                    }
                    picture.setPictureWidth(width);
                    picture.setPictureHeight(height);
                    Date photoTime = DateUtil.stringtoDate(photos[2], "yyyy:MM:dd HH:mm:ss");
//                    String strPhotoTime = ExifUitl.readTime(tempFile);
//                    Date photoTime = DateUtil.stringtoDate(strPhotoTime, "yyyy:MM:dd HH:mm:ss");
                    picture.setPhotoTime(photoTime);
                }catch(Exception e){
                    log.error(e.getMessage(), e);
                }finally {
                    if(tempFile!=null) {
                        //清除临时文件
                        FileUtil.deleteTempFile(tempFile);
                    }
                }
                int result = savePicture(picture);
//                if(i==1){
//                    int a = 1/0;//抛出ArithmeticException异常
//                }
                return result;
            }else{
                return 0;
            }

        }catch(IOException ioe){
            log.error(ioe.getMessage(), ioe);
            throw new RuntimeException(ioe);
        }finally{
            //删除临时压缩文件
            FileUtil.deleteTempFile(zoomFile);
            //删除临时水印文件
            FileUtil.deleteTempFile(watermarkFile);
            //上传临时git图片
            FileUtil.deleteTempFile(file);
        }

    }

    /**
     *
     * @param ids
     * @return
     */
    public Result deletePicture2Recycle(Integer[] ids){
        int failCount = 0;
        int successCount = 0;
        PictureService proxy = (PictureService) AopContext.currentProxy();
        for(Integer id:ids){
            try{
                Result result = proxy.deletePicture2Recycle(id);
                if(result.getStatus().intValue()==200){
                    successCount++;
                }else{
                    failCount++;
                }
            }catch(Exception e){
                log.error(e.getMessage(), e);
                failCount++;
            }
        }
        if(failCount==0){
            return Result.success("删除"+successCount+"个图片到回收站成功");
        }else if(successCount==0){
            return Result.error("删除"+successCount+"个图片到回收站失败，原因可能是图片被使用", "删除"+successCount+"个图片到回收站失败，原因可能是图片被使用");
        }else{
            return Result.custom(400, failCount+"个图片删除到回收站失败,原因可能是图片被使用"+successCount+"个图片删除到回收站成功", failCount+"个图片删除到回收站失败,"+successCount+"个图片删除到回收站成功");
        }
    }

    /**
     *
     * @param ids
     * @return
     */
    public Result deletePictureFromRecycle(Integer[] ids){
        int failCount = 0;
        int successCount = 0;
        PictureService proxy = (PictureService) AopContext.currentProxy();
        for(Integer id:ids){
            try{
                proxy.deletePictureFromRecycle(id);
                successCount++;
            }catch(Exception e){
                log.error(e.getMessage(), e);
                failCount++;
            }
        }
        if(failCount==0){
            return Result.success("批量删除"+successCount+"个图片到回收站成功");
        }else{
            return Result.success(failCount+"个图片删除到回收站失败,"+successCount+"个图片删除到回收站成功");
        }
    }


    /**
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Throwable.class)
    public Result deletePictureFromRecycle(Integer id){
//        Picture picture = new Picture();
//        picture.setId(id);
//        picture.setDeleteStatus(2);
//        picture.setUpdateTime(new Date(System.currentTimeMillis()));
//        int count = pictureMapper.updatePicture(picture);
//        if(count>0){
//            return Result.success("从回收站删除图片成功");
//        }else{
//            return Result.error("从回收站删除图片成功");
//        }
        //首先查询
        Picture picture = pictureMapper.selectByPrimaryKey(id);
        //其次删除数据库中该图片的记录
        if(picture==null){
            return Result.error("没有这个图片id="+id);
        }
        if(picture.getDeleteStatus()!=1){
            return Result.error("图片不在回收站中，不能彻底删除,id="+id);
        }
        int count = pictureMapper.deleteByPrimaryKey(id);
//        int count = 1;
        if(count>0){
            //最后删除阿里云oss中该图片
            String pictureUrl = picture.getPictureUrl();
            boolean b = ossComponent.deleteFromOSS(pictureUrl);
            log.info("删除图片库图片{}结果{}", pictureUrl, b);
            return Result.success("删除图片成功");
        }else{
            return Result.error("删除图片失败");
        }

    }

    /**
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Throwable.class)
    public Result deletePicture2Recycle(Integer id){
        Picture dbPicture = pictureMapper.selectByPrimaryKey(id);
        if(dbPicture==null){
            return Result.error("没有该图片");
        }
        if(dbPicture.getUseCount()>0){
            return Result.error("图片被使用，不能删除");
        }
        Picture picture = new Picture();
        picture.setId(id);
        picture.setDeleteStatus(1);
        Date currentTime = new Date(System.currentTimeMillis());
        picture.setUpdateTime(currentTime);
        picture.setRecycleTime(currentTime);
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("删除图片到回收站成功");
        }else{
            return Result.error("删除图片到回收站失败");
        }
        //首先删除数据库中该图片的记录
        //int count = pictureMapper.deleteByPrimaryKey(id);
//        int count = 1;
//        if(count>0){
//            //其次删除阿里云oss中该图片
//            String pictureUrl = picture.getPictureUrl();
//            ossComponent.deleteFromOSS(pictureUrl);
//            return Result.success("删除图片成功");
//        }else{
//            return Result.error("删除图片失败");
//        }

    }

    /**
     * 修改图片名称
     * @param id
     * @param newPictureName
     * @return
     */
    public Result updatePictureName(Integer id, String newPictureName){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setPictureName(newPictureName);
        picture.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("修改图片名称成功");
        }else{
            return Result.error("修改图片名称失败");
        }
    }

    /**
     * 修改图片标签
     * @param id
     * @param newPictureAlt
     * @return
     */
    public Result updatePictureAlt(Integer id, String newPictureAlt){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setPictureAlt(newPictureAlt);
        picture.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("重命名图片标签成功");
        }else{
            return Result.error("重命名图片标签失败");
        }

    }

    /**
     * 修改图片信息
     * @param id
     * @param newPictureInfo
     * @return
     */
    public Result updatePictureInfo(Integer id, String newPictureInfo){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setPictureInfo(newPictureInfo);
        picture.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("重命名图片信息成功");
        }else{
            return Result.error("重命名图片信息失败");
        }

    }

    /**
     * 修改图片摄影记者
     * @param id
     * @param newPhotographer
     * @return
     */
    public Result updatePhotographer(Integer id, String newPhotographer){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setPhotographer(newPhotographer);
        picture.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("修改图片摄影记者成功");
        }else{
            return Result.error("修改图片摄影记者失败");
        }

    }

    /**
     * 更新图片使用状态
     * @param id
     * @param newPictureIsUse
     * @return
     */
//    public Result updatePictureIsUse(Integer id, Integer newPictureIsUse){
//        Picture oldPicture = pictureMapper.selectByPrimaryKey(id);
//        if(oldPicture.getPictureIsUse().intValue()==newPictureIsUse.intValue()){
//            log.info("图片使用状态相同，无需更新，图片id={}，原使用状态={}，新使用状态={}", id, oldPicture.getPictureIsUse(), newPictureIsUse);
//            return Result.success("图片使用状态无需更新");
//        }
//        Picture picture = new Picture();
//        picture.setId(id);
//        picture.setPictureIsUse(newPictureIsUse);
//        picture.setUpdateTime(new Date(System.currentTimeMillis()));
//        int count = pictureMapper.updatePicture(picture);
//        if(count>0){
//            return Result.success("更新图片使用状态成功");
//        }else{
//            return Result.error("更新图片使用状态失败");
//        }
//    }


    /**
     * 移动图片
     * @param ids
     * @param targetFolderId
     * @return
     */
    public Result movePicture(Integer[] ids, Integer targetFolderId){
        int failCount = 0;//文件移动失败数量
        int successCount = 0;//文件移动成功数量
        PictureService proxy = (PictureService) AopContext.currentProxy();
        for(Integer id:ids){
            //int count = movePicture(id, targetFolderId);
            int count = 0;
            try{
                count = proxy.movePicture(id, targetFolderId);
            }catch(Exception e){
                log.error(e.getMessage(), e);
            }
            if(count>0){
                successCount ++;
            }else{
                failCount ++;
            }
        }
        if(failCount==0){
            return Result.success("移动图片成功");
        }else{
            return Result.success(failCount+"个图片移动失败,"+successCount+"个图片移动成功");
        }
    }


    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Throwable.class)
    public int movePicture(Integer id, Integer targetFolderId){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setFolderId(targetFolderId);
        int count = pictureMapper.updatePicture(picture);
        return count;
    }

    /**
     * @return java.awt.image.BufferedImage
     * @throws
     * @description 操纵文字型水印
     * @params [text]
     */
    private BufferedImage handleTextWaterMark(String text) {

        BufferedImage image = new BufferedImage(80, 32, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        image = g.getDeviceConfiguration().createCompatibleImage(800, 320, Transparency.TRANSLUCENT);

        int y = 0;
        int divider30 = 30;

        g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.red);
        g.setFont(new Font("苹方", Font.PLAIN, 40));
        g.drawString(text, 5, y += divider30);

        g.dispose();
        return image;
    }




    public Result restorePicture(Integer[] ids){
        int failCount = 0;
        int successCount = 0;
        PictureService proxy = (PictureService) AopContext.currentProxy();
        for(Integer id:ids){
            try{
                proxy.restorePicture(id);
                successCount++;
            }catch (Exception e){
                log.error(e.getMessage(), e);
                failCount++;
            }
        }
        if(failCount==0){
            return Result.success("复原图片成功");
        }else{
            return Result.success(failCount+"个图片复原失败,"+successCount+"个图片复原成功");
        }
    }

    @Transactional(rollbackFor = Throwable.class)
    public Result restorePicture(Integer id){
        Picture picture = new Picture();
        picture.setId(id);
        picture.setDeleteStatus(0);
        picture.setUpdateTime(new Date(System.currentTimeMillis()));
        int count = pictureMapper.updatePicture(picture);
        if(count>0){
            return Result.success("从回收站复原图片成功");
        }else{
            return Result.error("从回收站复原图片失败");
        }

    }

    /**
     * 获取图片库使用空间--所有图片的size总和
     * @return
     */
    public Result getPictureTotalSize(){
        Long totalSize = pictureMapper.getPictureTotalSize();
        if(totalSize==null){
            totalSize=0L;
        }
        return Result.success(totalSize);
    }

    /**
     * 更新图片使用时间、使用次数
     * @param pictureUseParam
     * @return
     */
    public Result usePicture(PictureUseParam pictureUseParam){
        Date currentTime = new Date(System.currentTimeMillis());
        pictureUseParam.setLastUseTime(currentTime);
        int count = pictureMapper.updatePictureUse(pictureUseParam);
        if(count>0){
            return Result.success("更新图片使用时间、使用次数成功");
        }else{
            return Result.error("更新图片使用时间、使用次数失败");
        }
    }


    /**
     * 查询回收站中图片
     * @param pictureRecycleQueryParam
     * @return
     */
    public  PageInfo<Picture> queryPictureInRecycle(PictureRecycleQueryParam pictureRecycleQueryParam){
        Integer pictureType = pictureRecycleQueryParam.getPictureType();
        if(pictureType!=null){
            if(pictureType==PictureEnum.PICTURE_JPG.getType()){
                pictureRecycleQueryParam.setStrPictureType(PictureEnum.PICTURE_JPG.getNote());
            }else if(pictureType==PictureEnum.PICTURE_PNG.getType()){
                pictureRecycleQueryParam.setStrPictureType(PictureEnum.PICTURE_PNG.getNote());
            }else if(pictureType==PictureEnum.PICTURE_GIF.getType()){
                pictureRecycleQueryParam.setStrPictureType(PictureEnum.PICTURE_GIF.getNote());
            }
        }
        Page<?> page = PageHelper.startPage(pictureRecycleQueryParam.getPageNum(), pictureRecycleQueryParam.getPageSize());
        List<Picture> pictureList = pictureMapper.queryPictureInRecycle(pictureRecycleQueryParam);

        //设置文件夹全路径名称
        buildFullFolderName(pictureList);

        PageInfo<Picture> picturePageInfo = new PageInfo<>(pictureList);
        return picturePageInfo;
    }

    public Result clearRecycle(){
        //获取回收站所有的图片id
        List<Integer> ids = pictureMapper.listPictureIdInRecycle();
        int failCount = 0;
        int successCount = 0;
        PictureService proxy = (PictureService) AopContext.currentProxy();
        for(Integer id:ids){
            try{
                proxy.deletePictureFromRecycle(id);
                successCount++;
            }catch(Exception e){
                log.error(e.getMessage(), e);
                failCount++;
            }
        }
        if(failCount==0){
            return Result.success("清空回收站"+successCount+"个图片成功");
        }else{
            return Result.success("清空回收站"+failCount+"个图片失败,"+successCount+"个图片成功");
        }

    }
}
